package fr.imag.m2pgi.m2m.geoloc.visualizer;

import java.awt.BorderLayout;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.LineArray;
import javax.media.j3d.Shape3D;
import javax.swing.JFrame;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;

import com.sun.j3d.utils.universe.SimpleUniverse;




public class VisuaImpl extends JFrame implements Visualizer, WindowListener {
  

  int zmax;
  Map < Integer, Map<Double, Integer>>  listeMeasure;
  private Canvas3D canvas;
  
  VisuaImpl(){
    super("Visualisation");
    this.addWindowListener(this);
    this.setLayout(new BorderLayout());

    // creation de la scene java3d
    canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
    SimpleUniverse simpleU = new SimpleUniverse(canvas);
    BranchGroup visua = new BranchGroup();
    visua.compile();
    simpleU.addBranchGraph(visua);
    simpleU.getViewingPlatform().setNominalViewingTransform();
    this.add("Center", canvas);
  }

  

  public void addMeasure(Map<Double, Integer> data, int z) {
    Canvas3D prevCanvas =  canvas;
    canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
    SimpleUniverse simpleU = new SimpleUniverse(canvas);
    BranchGroup visua = new BranchGroup();
    
    this.zmax = z;
    double dz;
    LineArray lPaire = new LineArray(2, LineArray.COORDINATES | LineArray.COLOR_3);
    LineArray lImpaire = new LineArray(2, LineArray.COORDINATES | LineArray.COLOR_3); 
    
    //save in list
    listeMeasure.put(z,data);
    
    
    List<Integer> listeMap = new ArrayList<Integer>(listeMeasure.keySet());
    Collections.sort(listeMap);
//    System.out.println(listeMap.size());

    //
    for (int i = 0 ; i < listeMap.size() ; i++){
      
      Map<Double, Integer> map = listeMeasure.get(listeMap.get(i));
      System.out.println("lmg : "+listeMap.get(i));
      System.out.println("zmax : "+zmax);
      if(zmax == 0){
        dz = 0;
      }else{
        dz = (double) listeMap.get(i) / (double) zmax;
      }
      
      List<Double> liste = new ArrayList<Double>(map.keySet());
      Collections.sort(liste);
      
      
      for(int j = 0; j < liste.size(); j++ ){
        
        double angle = liste.get(j);
//        System.out.println(angle);
        int distance = map.get(angle);
//        System.out.println(distance);
        double x = 0.0 , y = 0.0;
        
        if (angle > 0.0) {
          x = Math.abs(Math.cos(Math.abs(angle - 90.0)) * distance / 5000);
        }
        if (angle == 0.0) {
          x = 0.0;
        }
        if (angle < 0.0) {
          x = -Math.abs(Math.cos(Math.abs(angle + 90.0)) * distance / 5000);
        }

        // calcul pour y
        if (-90.0 < angle && angle < 90.0) {
          y = Math.abs(Math.cos(Math.abs(angle)) * distance / 5000);
        }
        if (Math.abs(angle) == 90.0) {
          y = 0.0;
        }
        if (angle < -90.0) {
          y = -Math.abs(Math.cos(Math.abs(angle - 90.0)) * distance / 5000);
        }
        if (angle > 90.0) {
          y = -Math.abs(Math.cos(Math.abs(angle + 90.0)) * distance / 5000);
        }
        
        
        if (j % 2 == 0) {
          if (j != liste.size() - 1) {
            lPaire = new LineArray(2, LineArray.COORDINATES | LineArray.COLOR_3);
            lPaire.setCoordinate(0, new Point3d(x, y, dz));
            lPaire.setColor(0, new Color3f(1f, 0f, 0f));
          }

          if (j != 0) {
            lImpaire.setCoordinate(1, new Point3d(x, y, dz));
            lImpaire.setColor(1, new Color3f(1f, 0f, 0f));
            visua.addChild(new Shape3D(lImpaire));
          }
        }
        if (j % 2 == 1) {
          if (i != liste.size() - 1) {
            lImpaire = new LineArray(2, LineArray.COORDINATES | LineArray.COLOR_3);
            lImpaire.setCoordinate(0, new Point3d(x, y, dz));
            lImpaire.setColor(0, new Color3f(1f, 0f, 0f));
          }
          lPaire.setCoordinate(1, new Point3d(x, y, dz));
          lPaire.setColor(1, new Color3f(1f, 0f, 0f));
          visua.addChild(new Shape3D(lPaire));

        }
        
        System.out.println("(" + x + " ; " + y + " ; " + dz + ")");
        
      }//for j
      
    }// for i
    visua.compile();
    simpleU.addBranchGraph(visua);
    simpleU.getViewingPlatform().setNominalViewingTransform();
    this.remove(prevCanvas);
    this.add(canvas,0);
    repaint();
  }

  public void init(int z) {
    // Initialisation de la fenêtre
    listeMeasure = new HashMap < Integer, Map<Double, Integer>>() ;
    setSize(400, 400);
    setVisible(true);
  }

  public void reset() {
    // TODO Auto-generated method stub
    
  }

  public void windowActivated(WindowEvent arg0) {}

  public void windowClosed(WindowEvent arg0) {}

  public void windowClosing(WindowEvent arg0) {
    System.exit(1);
  }

  public void windowDeactivated(WindowEvent arg0) {}

  public void windowDeiconified(WindowEvent arg0) {}

  public void windowIconified(WindowEvent arg0) {}

  public void windowOpened(WindowEvent arg0) {}
  
  public static void main(final String args[]) {
    
    VisuaImpl visual = new VisuaImpl();
    
    visual.init(0);
    Map<Double, Integer> map = new HashMap<Double, Integer>();
    map.put(-92.0,2500);
    map.put(-45.0,2230);
    map.put(45.0,2230);
    map.put(92.0,2500);
    visual.addMeasure(map,0);
//    visual.setVisible(true);
//    visual.setVisible(true);
//    visual.setVisible(true);
//    visual.setVisible(true);
    visual.addMeasure(map,3);
    visual.addMeasure(map,15);
    visual.setVisible(true);
    
  }
  
}
